package test.simpleFactory;


import java.math.BigDecimal;

/***
 * 简单工厂模式
 * 实现需求：实现一个计算器(两个数的加减乘除就可以了)
 * 好处：
 * 1.解耦，客户端和服务端的解耦，客户端不必关心服务端的实现
 * 2.可扩展，如果增加其他运算类，只需要添加一个Operation的实现，并且在工厂类中增加分支就可以了(当然，这里在工厂类中增加分支也不太好，违背了开放-封闭原则)
 * 3.可维护性，某个运算类的具体实现直接在其实现中修改就好了，就算修改出错，也不会影响所有的运算
 * 4.使用简便，客户端不需要知道具体创建什么类，只要知道参数就好了
 * 缺点：
 * 1.工厂类的职责过于沉重，一旦getOperationInstance方法出现异常，那么，整个服务将不可使用
 * 2.假如我只增加一个很简单的功能，但是也得创建一个类，这样会让系统的类越来越多
 * */
public class SimpleFactory {
    // 客户端代码
    public static void main(String[] args) {
        // 通过工厂类获取具体的实现
        Operation operation = OperationFactory.getOperationInstance("-");
        operation.setNumbers(new BigDecimal(1),new BigDecimal(1));
        System.out.print("结果："+operation.getResult());

    }


}

/**
 * 定义运算的抽象类
 * */
class OperationFactory{

    public static Operation getOperationInstance(String operationStr){
        switch (operationStr){
            case "+":
                return new Add();
            case "-":
                return new Subtract();
            default:
                throw new RuntimeException("没有这个");
        }
    }

}


/**
 * 定义运算的父类
 * */
abstract class Operation{

    // 数字A
    protected BigDecimal numberA;

    // 数字B
    protected BigDecimal numberB;

    // 设置数字
    public void setNumbers(BigDecimal numberA,BigDecimal numberB){
        this.numberA = numberA;
        this.numberB = numberB;
    }


    // 定义一个抽象方法，其子类必须实现此方法
    public abstract BigDecimal getResult();

}

/**
 * 定义运算的子类 +
 * */
class Add extends Operation{

    public BigDecimal getResult() {
        return numberA.add(numberB);
    }
}


/**
 * 定义运算的子类 -
 * */
class Subtract extends Operation{

    public BigDecimal getResult() {
        return numberA.subtract(numberB);
    }
}